#ifndef __XMODEM_H__
#define __XMODEM_H__

#define XMODEM_DATA_LEN     512
#define XMODEM_CRCPKG_LEN   (XMODEM_DATA_LEN+1+2+2)   // headr(1byte) + sequeye + ~sequeue + crc16
#define XMODEM_FINFO_LEN     sizeof(FINFO_STRU)
#define XMODEM_RETRY           10
#define XMODEM_TIMEOUT_RETRY           2

#define XERR_NO_ERROR           0
#define XERR_CRC                    -1
#define XERR_SEQ                    -2
#define XERR_HEADER              -3
#define XERR_INVALID_PARA   -4
#define XERR_SYSCALL             -5
#define XERR_TIMEOUT            -6
#define XERR_FATAL                 -7

typedef enum STAT
{
    EN_R_INIT,
    EN_R_FINFO,
    EN_R_NAK,
    EN_R_ACK,
    EN_R_EOF,
    EN_R_FIN,
    EN_S_INIT,
    EN_S_FINFO,
    EN_S_PKG,
    EN_S_EOF,
    EN_S_WACK,
    EN_S_WEOFACK,
    EN_RS_NUM
}STAT_ENUM;

typedef enum VERIFICATION
{
    EN_CKSUM,
    EN_CRC16,
    EN_NUM
}VERIFICATION_ENUM;

typedef union verify
{
    unsigned short crc;
    unsigned char cksum;
}__attribute__((packed)) verify_union;

typedef struct XPACKAGE
{
    unsigned char head;
    unsigned char seq;
    unsigned char xseq;
    unsigned char data[XMODEM_DATA_LEN];
    unsigned short v;
    //verify_union v;
}__attribute__((packed)) XPACKAGE_STRU;

typedef struct FINFO
{
     unsigned char head;
     unsigned long fsize;
     unsigned short v;
     //verify_union v;
}__attribute__((packed)) FINFO_STRU;

int xmodem_recv( int fd, FILE* fp);
int xmodem_send( int fd, FILE* fp);

#endif /* __XMODEM_H__ */
